package com.cencat.order.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 配送跟踪数据传输对象
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Data
@Accessors(chain = true)
public class DeliveryDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 配送ID(更新时必填)
     */
    private Long deliveryId;

    /**
     * 配送编号
     */
    @Size(max = 50, message = "配送编号长度不能超过50个字符")
    private String deliveryCode;

    /**
     * 订单ID
     */
    @NotNull(message = "订单ID不能为空")
    private Long orderId;

    /**
     * 订单编号
     */
    @Size(max = 50, message = "订单编号长度不能超过50个字符")
    private String orderCode;

    /**
     * 派单ID
     */
    private Long dispatchId;

    /**
     * 派单编号
     */
    @Size(max = 50, message = "派单编号长度不能超过50个字符")
    private String dispatchCode;

    /**
     * 司机ID
     */
    @NotNull(message = "司机ID不能为空")
    private Long driverId;

    /**
     * 司机编号
     */
    @Size(max = 50, message = "司机编号长度不能超过50个字符")
    private String driverCode;

    /**
     * 司机姓名
     */
    @Size(max = 50, message = "司机姓名长度不能超过50个字符")
    private String driverName;

    /**
     * 司机手机号
     */
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "司机手机号格式不正确")
    private String driverPhone;

    /**
     * 车辆ID
     */
    private Long vehicleId;

    /**
     * 车牌号
     */
    @Size(max = 20, message = "车牌号长度不能超过20个字符")
    private String vehiclePlateNumber;

    /**
     * 商家ID
     */
    private Long merchantId;

    /**
     * 商家编号
     */
    @Size(max = 50, message = "商家编号长度不能超过50个字符")
    private String merchantCode;

    /**
     * 商家名称
     */
    @Size(max = 100, message = "商家名称长度不能超过100个字符")
    private String merchantName;

    /**
     * 配送状态(0-待取货 1-已取货 2-运输中 3-已到达 4-配送中 5-已签收 6-异常 7-已取消)
     */
    @Min(value = 0, message = "配送状态值不正确")
    @Max(value = 7, message = "配送状态值不正确")
    private Integer deliveryStatus;

    /**
     * 配送类型(1-普通配送 2-加急配送 3-定时配送 4-预约配送)
     */
    @NotNull(message = "配送类型不能为空")
    @Min(value = 1, message = "配送类型值不正确")
    @Max(value = 4, message = "配送类型值不正确")
    private Integer deliveryType;

    /**
     * 优先级(1-低 2-中 3-高 4-紧急)
     */
    @Min(value = 1, message = "优先级值不正确")
    @Max(value = 4, message = "优先级值不正确")
    private Integer priority;

    /**
     * 货物名称
     */
    @Size(max = 200, message = "货物名称长度不能超过200个字符")
    private String goodsName;

    /**
     * 货物类型
     */
    @Size(max = 50, message = "货物类型长度不能超过50个字符")
    private String goodsType;

    /**
     * 货物重量(公斤)
     */
    @DecimalMin(value = "0.1", message = "货物重量不能小于0.1公斤")
    private BigDecimal goodsWeight;

    /**
     * 货物体积(立方米)
     */
    @DecimalMin(value = "0.01", message = "货物体积不能小于0.01立方米")
    private BigDecimal goodsVolume;

    /**
     * 货物数量
     */
    @Min(value = 1, message = "货物数量不能小于1")
    private Integer goodsQuantity;

    /**
     * 货物价值
     */
    @DecimalMin(value = "0.0", message = "货物价值不能小于0")
    private BigDecimal goodsValue;

    /**
     * 取货地址
     */
    @NotBlank(message = "取货地址不能为空")
    @Size(max = 200, message = "取货地址长度不能超过200个字符")
    private String pickupAddress;

    /**
     * 取货联系人
     */
    @Size(max = 50, message = "取货联系人长度不能超过50个字符")
    private String pickupContactPerson;

    /**
     * 取货联系电话
     */
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "取货联系电话格式不正确")
    private String pickupContactPhone;

    /**
     * 配送地址
     */
    @NotBlank(message = "配送地址不能为空")
    @Size(max = 200, message = "配送地址长度不能超过200个字符")
    private String deliveryAddress;

    /**
     * 配送联系人
     */
    @Size(max = 50, message = "配送联系人长度不能超过50个字符")
    private String deliveryContactPerson;

    /**
     * 配送联系电话
     */
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "配送联系电话格式不正确")
    private String deliveryContactPhone;

    /**
     * 计划取货时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime plannedPickupTime;

    /**
     * 实际取货时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime actualPickupTime;

    /**
     * 计划配送时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime plannedDeliveryTime;

    /**
     * 实际配送时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime actualDeliveryTime;

    /**
     * 签收时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime signTime;

    /**
     * 签收人
     */
    @Size(max = 50, message = "签收人长度不能超过50个字符")
    private String signPerson;

    /**
     * 签收方式(1-本人签收 2-代收 3-放置指定位置 4-智能柜)
     */
    @Min(value = 1, message = "签收方式值不正确")
    @Max(value = 4, message = "签收方式值不正确")
    private Integer signType;

    /**
     * 签收照片
     */
    @Size(max = 500, message = "签收照片长度不能超过500个字符")
    private String signPhoto;

    /**
     * 当前位置经度
     */
    @DecimalMin(value = "-180.0", message = "当前位置经度值不正确")
    @DecimalMax(value = "180.0", message = "当前位置经度值不正确")
    private BigDecimal currentLongitude;

    /**
     * 当前位置纬度
     */
    @DecimalMin(value = "-90.0", message = "当前位置纬度值不正确")
    @DecimalMax(value = "90.0", message = "当前位置纬度值不正确")
    private BigDecimal currentLatitude;

    /**
     * 当前位置地址
     */
    @Size(max = 200, message = "当前位置地址长度不能超过200个字符")
    private String currentAddress;

    /**
     * 位置更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime locationUpdateTime;

    /**
     * 预计距离(公里)
     */
    @DecimalMin(value = "0.1", message = "预计距离不能小于0.1公里")
    private BigDecimal estimatedDistance;

    /**
     * 实际距离(公里)
     */
    @DecimalMin(value = "0.0", message = "实际距离不能小于0")
    private BigDecimal actualDistance;

    /**
     * 预计时长(分钟)
     */
    @Min(value = 1, message = "预计时长不能小于1分钟")
    private Integer estimatedDuration;

    /**
     * 实际时长(分钟)
     */
    @Min(value = 0, message = "实际时长不能小于0分钟")
    private Integer actualDuration;

    /**
     * 配送费用
     */
    @DecimalMin(value = "0.0", message = "配送费用不能小于0")
    private BigDecimal deliveryFee;

    /**
     * 燃油费
     */
    @DecimalMin(value = "0.0", message = "燃油费不能小于0")
    private BigDecimal fuelFee;

    /**
     * 过路费
     */
    @DecimalMin(value = "0.0", message = "过路费不能小于0")
    private BigDecimal tollFee;

    /**
     * 其他费用
     */
    @DecimalMin(value = "0.0", message = "其他费用不能小于0")
    private BigDecimal otherFee;

    /**
     * 总费用
     */
    @DecimalMin(value = "0.0", message = "总费用不能小于0")
    private BigDecimal totalFee;

    /**
     * 异常类型(1-货物损坏 2-货物丢失 3-地址错误 4-联系不上 5-拒收 6-其他)
     */
    @Min(value = 1, message = "异常类型值不正确")
    @Max(value = 6, message = "异常类型值不正确")
    private Integer exceptionType;

    /**
     * 异常描述
     */
    @Size(max = 500, message = "异常描述长度不能超过500个字符")
    private String exceptionDesc;

    /**
     * 异常处理状态(0-未处理 1-处理中 2-已处理)
     */
    @Min(value = 0, message = "异常处理状态值不正确")
    @Max(value = 2, message = "异常处理状态值不正确")
    private Integer exceptionHandleStatus;

    /**
     * 异常处理人
     */
    @Size(max = 50, message = "异常处理人长度不能超过50个字符")
    private String exceptionHandler;

    /**
     * 异常处理时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime exceptionHandleTime;

    /**
     * 异常处理结果
     */
    @Size(max = 500, message = "异常处理结果长度不能超过500个字符")
    private String exceptionHandleResult;

    /**
     * 客户评价分数(1-5分)
     */
    @Min(value = 1, message = "客户评价分数不能小于1分")
    @Max(value = 5, message = "客户评价分数不能大于5分")
    private Integer customerRating;

    /**
     * 客户评价内容
     */
    @Size(max = 500, message = "客户评价内容长度不能超过500个字符")
    private String customerComment;

    /**
     * 客户评价时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime customerRatingTime;

    /**
     * 司机评价分数(1-5分)
     */
    @Min(value = 1, message = "司机评价分数不能小于1分")
    @Max(value = 5, message = "司机评价分数不能大于5分")
    private Integer driverRating;

    /**
     * 司机评价内容
     */
    @Size(max = 500, message = "司机评价内容长度不能超过500个字符")
    private String driverComment;

    /**
     * 司机评价时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime driverRatingTime;

    /**
     * 温度要求(摄氏度)
     */
    @DecimalMin(value = "-50.0", message = "温度要求不能小于-50摄氏度")
    @DecimalMax(value = "100.0", message = "温度要求不能大于100摄氏度")
    private BigDecimal temperatureRequirement;

    /**
     * 湿度要求(%)
     */
    @DecimalMin(value = "0.0", message = "湿度要求不能小于0%")
    @DecimalMax(value = "100.0", message = "湿度要求不能大于100%")
    private BigDecimal humidityRequirement;

    /**
     * 特殊要求
     */
    @Size(max = 500, message = "特殊要求长度不能超过500个字符")
    private String specialRequirements;

    /**
     * 保险金额
     */
    @DecimalMin(value = "0.0", message = "保险金额不能小于0")
    private BigDecimal insuranceAmount;

    /**
     * 是否需要回单
     */
    private Boolean needReceipt;

    /**
     * 回单照片
     */
    @Size(max = 500, message = "回单照片长度不能超过500个字符")
    private String receiptPhoto;

    /**
     * 备注
     */
    @Size(max = 500, message = "备注长度不能超过500个字符")
    private String remark;

    /**
     * 扩展字段1
     */
    @Size(max = 200, message = "扩展字段1长度不能超过200个字符")
    private String extField1;

    /**
     * 扩展字段2
     */
    @Size(max = 200, message = "扩展字段2长度不能超过200个字符")
    private String extField2;

    /**
     * 扩展字段3
     */
    @Size(max = 200, message = "扩展字段3长度不能超过200个字符")
    private String extField3;

    /**
     * 配送轨迹列表
     */
    private List<DeliveryTrackDTO> deliveryTracks;

    /**
     * 配送轨迹数据传输对象
     */
    @Data
    @Accessors(chain = true)
    public static class DeliveryTrackDTO implements Serializable {

        private static final long serialVersionUID = 1L;

        /**
         * 轨迹ID
         */
        private Long trackId;

        /**
         * 轨迹时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime trackTime;

        /**
         * 经度
         */
        @NotNull(message = "经度不能为空")
        @DecimalMin(value = "-180.0", message = "经度值不正确")
        @DecimalMax(value = "180.0", message = "经度值不正确")
        private BigDecimal longitude;

        /**
         * 纬度
         */
        @NotNull(message = "纬度不能为空")
        @DecimalMin(value = "-90.0", message = "纬度值不正确")
        @DecimalMax(value = "90.0", message = "纬度值不正确")
        private BigDecimal latitude;

        /**
         * 地址
         */
        @Size(max = 200, message = "地址长度不能超过200个字符")
        private String address;

        /**
         * 速度(km/h)
         */
        @DecimalMin(value = "0.0", message = "速度不能小于0")
        @DecimalMax(value = "200.0", message = "速度不能大于200km/h")
        private BigDecimal speed;

        /**
         * 方向角(度)
         */
        @DecimalMin(value = "0.0", message = "方向角不能小于0度")
        @DecimalMax(value = "360.0", message = "方向角不能大于360度")
        private BigDecimal direction;

        /**
         * 海拔(米)
         */
        @DecimalMin(value = "-1000.0", message = "海拔不能小于-1000米")
        @DecimalMax(value = "10000.0", message = "海拔不能大于10000米")
        private BigDecimal altitude;

        /**
         * 轨迹状态(1-正常 2-异常 3-停留)
         */
        @Min(value = 1, message = "轨迹状态值不正确")
        @Max(value = 3, message = "轨迹状态值不正确")
        private Integer trackStatus;

        /**
         * 里程(公里)
         */
        @DecimalMin(value = "0.0", message = "里程不能小于0")
        private BigDecimal mileage;

        /**
         * 备注
         */
        @Size(max = 200, message = "备注长度不能超过200个字符")
        private String remark;
    }
}